﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ResourceLoadBalancer.Client;
using ResourceLoadBalancer.WebServices.Clients.Helpers;
using ResourceLoadBalancer.WebServices.Contracts.Data;
using System.IO;
using System.Net;
using System.Security.AccessControl;
using System.Xml;

namespace FileDuplicateFinderHasher
{
    public class FileSystemHasher:FileHasher
    {
        private static int BATCH_SIZE = 100;
        private static string FILE_SYSTEM_QUEUE_TYPE = "FileSystem";
        

        public FileSystemHasher()
        {
            hostName = Dns.GetHostName();
        }

        public void DeconfigureQueuing(string queueName)
        {
            this.queueName = queueName;
            if (serviceClient.IsServiceAvailable())
            {
                base.DeconfigureQueuing(FILE_SYSTEM_QUEUE_TYPE, queueName);
            }
            else
            {
                Console.WriteLine("Service unavailable");
            }
        }

        public void ProcessResourceQueue(string queueName)
        {
            
            this.queueName = queueName;
            string queuedItem = "";

            if (serviceClient.IsServiceAvailable())
            {

                try
                {
                    queuedItem = serviceClient.GetQueuedFileSystemResourceURI(hostName, queueName);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }

                while (!queuedItem.Equals(""))
                {
                    XmlDocument document = new XmlDocument();
                    document.Load(new StringReader(queuedItem));
                    HashResource(document.FirstChild.InnerText);
                    Console.WriteLine(document.FirstChild.InnerText);

                    try
                    {
                        queuedItem = serviceClient.GetQueuedFileSystemResourceURI(hostName, queueName);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }

                    if (Resources.Count == BATCH_SIZE)
                    {
                        SubmitResources(BATCH_SIZE);
                    }

                    if (ResourcesURI.Count == BATCH_SIZE)
                    {
                        SubmitResourceURIs(BATCH_SIZE);
                    }

                }
                SubmitResources(BATCH_SIZE);
                SubmitResourceURIs(BATCH_SIZE);
            }
            else
            {
                Console.WriteLine("Service unavailable");
            }
        }

        public void HashResource(string path)
        {
            MD5Utility md5Utility = new MD5Utility();

            
            ResourceLoadBalancerServiceClientHelper resourceLoadBalancerServiceClientHelper = new ResourceLoadBalancerServiceClientHelper();

            ResourceURIDataContract resourceURI = new ResourceURIDataContract();
            string owner = "";

            try
            {
                FileInfo file = new FileInfo(path);

                resourceURI.URI = file.FullName;
                resourceURI.HostName = hostName;

                resourceURI.URIHash = md5Utility.CalculateMD5Hash(file.FullName);

                try
                {
                    FileSecurity fsec = file.GetAccessControl(AccessControlSections.Owner);

                    owner = fsec.GetOwner(typeof(System.Security.Principal.NTAccount)).Value;
                }
                catch (Exception)
                {
                    owner = "unavailable";
                }

                resourceURI.Owner = owner;
                resourceURI.LastModifiedDate = file.LastWriteTime;
                resourceURI.CreatedDate = file.CreationTime;
                resourceURI.InventoryDate = DateTime.Now;

                try
                {

                    ResourceDataContract resource = md5Utility.CalculateMD5Hash(file);
                    resourceURI.ResourceHash = resource.Hash;
                    Resources.Add(resource);
                    ResourcesURI.Add(resourceURI);


                }
                catch (Exception ex)
                {

                    Console.Write(ex.Message);
                }
            }
            catch (Exception ex)
            {
                Console.Write(ex.Message);
            }
        }
    }
}
